#region Using References

using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Net;
using Beaker.OpenCube.CubeManager.Model.Framework;
using Beaker.OpenCube.CubeManager.Model.Interfaces;

#endregion

namespace Beaker.OpenCube.CubeManager.Model.Entities
{
	public class Machine
		: Entity, INamed
	{
		private readonly EntitySet<Server, Machine> _servers;
		private readonly EntitySet<RoleSet, Machine> _roleSets; 

		/// <summary>
		/// Create a new machine with the given name.
		/// </summary>
		/// <param name="machineName">The name of the machine.</param>
		public Machine( string machineName )
			: this()
		{
			Name = machineName;
		}

		/// <remarks>Internal constructor for EF</remarks>
		internal Machine()
		{
			_servers = new EntitySet<Server, Machine>( this, ( s, m ) => s.HostingMachine = m );
			_roleSets = new EntitySet<RoleSet, Machine>( this );
		}

		/// <summary>
		/// Gets the name of this server.
		/// </summary>
		/// <value>
		/// The name of this server.
		/// </value>
		[StringLength( 64 )]
		public string Name { get; internal set; }

		/// <summary>
		/// Gets or sets the IP address as a string.
		/// </summary>
		/// <value>
		/// The IP address as a string.
		/// </value>
		/// <remarks>
		/// This field is for EF serialization
		/// </remarks>
		[StringLength( 45 )] // max length of an ipv6 address (ipv4's are shorter)
		[EditorBrowsable( EditorBrowsableState.Never )] // hide this EF only field for code
		internal string IPAddressString
		{
			get
			{
				if( IPAddress == null )
					return null;

				return IPAddress.ToString();
			}
			set
			{
				if( value == null )
					IPAddress = null;
				else
					IPAddress = IPAddress.Parse( value );
			}
		}

		/// <summary>
		/// Gets or sets the IP address of the machine.
		/// </summary>
		/// <value>
		/// The IP address the machine.
		/// </value>
		public IPAddress IPAddress { get; internal set; }

		/// <summary>
		/// Gets the set of servers that are on this machine.
		/// </summary>
		/// <value>
		/// The servers on this machine.
		/// </value>
		public ISet<Server> Servers
		{
			get { return _servers; }
		}

		/// <summary>
		/// Gets the set of rolesets for this machine
		/// </summary>
		public ISet<RoleSet> RoleSets
		{
			get { return _roleSets; }
		}
	}
}